package automata.modelo;

import java.util.ArrayList;
import java.util.HashSet;




public class Automata {
	/**Enumeracion para manejar el tipo AF Determinista o No determinista*/
	public enum tipoEnum {DETERMINISTA, NO_DETERMINISTA};
	public static final char SIMBOLO_VACIO = '@'; 
	 
	public Automata ()
	{
		estadosFinales = new HashSet<String>();
		estados = new ArrayList<String>();
		simbolos = new ArrayList<Character>();
		transiciones = new ArrayList<Transicion>();
	}
	
	private tipoEnum tipo;
	private ArrayList<Character> simbolos;
	private ArrayList<String> estados; 
	private String estadoInicial;
	private HashSet<String> estadosFinales;
	private ArrayList<Transicion> transiciones;
	

	public ArrayList<Transicion> getTransiciones() {
		return transiciones;
	}

	public void setTransiciones(ArrayList<Transicion> transiciones) {
		this.transiciones = new ArrayList<Transicion>(transiciones);
	}

	public tipoEnum getTipo() {
		return tipo;
	}

	public void setTipo(tipoEnum tipo) {
		this.tipo = tipo;
	}

	public ArrayList<Character> getSimbolos() {
		return simbolos;
	}

	public void setSimbolos(ArrayList<Character> simbolos) {
		this.simbolos = simbolos;
	}

	public ArrayList<String> getEstados() {
		return estados;
	}

	public void setEstados(ArrayList<String> estados) {
		this.estados = estados;
	}

	
	public String getEstadoInicial() {
		return estadoInicial;
	}

	public void setEstadoInicial(String estadoInicial) {
		this.estadoInicial = estadoInicial;
	}

	public HashSet<String> getEstadosFinales() {
		return estadosFinales;
	}

	public void setEstadosFinales(HashSet<String> estadosFinales) {
		this.estadosFinales = estadosFinales;
	}
	
	/**
	 * Agrega un simbolo al conjunto E de simbolos de entrada.
	 * @param Character
	 * @return boolean
	 */
	public boolean addSimbolo(Character c){
		if(simbolos.contains(c)) 
			return false;
		else
		{
			simbolos.add(c);
			return true;
		}
	}
	
	/**
	 * Agrega un estado al conjunto Q de estados del automata.
	 * @param String
	 * @return boolean
	 */
	public boolean addEstado(String edo){
		if(estados.contains(edo)) 
			return false;
		else
		{
			estados.add(edo);
			return true;
		}
	}
	
	/**
	 * Agrega un estado al conjunto Q de estados del automata.
	 * @param int
	 * @return boolean
	 */
	public boolean addEstado(int edo){
		if(estados.contains(edo)) 
			return false;
		else
		{
			estados.add(Integer.toString(edo));
			return true;
		}
	}
	/**
	 * Regresa el número de simbolos que contiene el conjunto E.
	 * @return int
	 * */
	public int getCountSimbolos(){
		return simbolos.size();
	}
	       
	/**
	 * Regresa el número de estados que contiene el conjunto Q.
	 * @return int
	 * */
	public int getCountEstados(){
		return estados.size();
	}
	
	public int getCountTransiciones(){
		return transiciones.size();
	}

	public String nombra(int nombre) {
		return new String("q" + nombre%100);
	}

	public void addEstadoFinal(String estado) {
		estadosFinales.add(estado);		
	}
	
	public boolean esFinal(String estado){
		return estadosFinales.contains(estado) ? true : false ;		
	}
	
	public void addTransicion(String desde, Character simb, String hasta){
		Transicion t = new Transicion();
		t.setDesde(Integer.valueOf(desde));
		t.setSimbolo(simb);
		t.setHasta(Integer.valueOf(hasta));
		System.out.println(t.getDesde() + t.getSimbolo()+t.getHasta());
		if(!transiciones.contains(t)) this.transiciones.add(t);
	}

}
